package wordctrl

import (
	"context"
	"rewords-server-2024/internal/consts"
	"rewords-server-2024/internal/service"
	"rewords-server-2024/utility/ufun"
	"strings"

	wordAPI "rewords-server-2024/api/word"
	"rewords-server-2024/internal/model/entity"
	"rewords-server-2024/internal/model/input/query_in"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"go.mongodb.org/mongo-driver/bson"
)

type cWordCtrl struct{}

var WordCtrl = new(cWordCtrl)

// QueryList 获取词库列表
func (c *cWordCtrl) QueryList(ctx context.Context, req *wordAPI.WordsListReq) (res *wordAPI.WordsListRes, err error) {
	// 设置要查询的字段
	fieldSelect := []string{
		"_id", "wordRank", "headWord", "content", "bookId",
	}

	// 构建查询条件
	query, skip, limit, sortFields, projection := query_in.BuildMongoQueryWithPage(req.Conditions, req.OrderFields, req.Page, fieldSelect)
	g.Log().Debug(ctx, "MongoDB query conditions:", query)
	g.Log().Debug(ctx, "Skip:", skip, "Limit:", limit)

	// 执行查询
	result, err := service.Mgx().Find(ctx, consts.CWordDict, query, projection, skip, limit, sortFields)
	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}

	// 转换结果
	var lists []entity.WordDict
	if err = gconv.Struct(result, &lists); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	// 获取总记录数
	var total int64
	if req.Page.QueryCount {
		total, err = service.Mgx().CountDocuments(ctx, consts.CWordDict, query)
		if err != nil {
			return nil, gerror.Wrap(err, "获取总记录数失败")
		}
	}

	// 构建返回结果
	res = &wordAPI.WordsListRes{
		Data: ufun.If(len(lists) > 0, lists, []entity.WordDict{}),
		PageResult: query_in.PageResult{
			Current:  (skip / limit) + 1,
			PageSize: limit,
			Total:    total,
			Pages:    (total + limit - 1) / limit,
			HasNext:  (skip + limit) < total,
		},
	}

	return res, nil
}

// QueryOne 获取单个词条
func (c *cWordCtrl) QueryOne(ctx context.Context, req *wordAPI.WordOneReq) (res *wordAPI.WordOneRes, err error) {
	// 构建查询条件
	query := c.buildWordQuery(req.Q)
	g.Log().Debug(ctx, "MongoDB query conditions:", query)

	// 执行查询
	result, err := service.Mgx().FindOne(ctx, consts.CWordDict, query, nil)
	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}

	// 转换结果
	var word entity.WordDict
	if err = gconv.Struct(result, &word); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	// 构建返回结果
	res = &wordAPI.WordOneRes{
		WordDict: word,
	}

	return res, nil
}

// buildWordQuery 构建单词查询条件
func (c *cWordCtrl) buildWordQuery(q string) bson.M {
	// 如果包含通配符，则使用正则表达式
	if strings.ContainsAny(q, "%_") {
		// 将SQL通配符转换为正则表达式
		regexPattern := strings.ReplaceAll(q, "%", ".*")
		regexPattern = strings.ReplaceAll(regexPattern, "_", ".")
		regexPattern = "^" + regexPattern + "$"

		return bson.M{
			"headWord": bson.M{
				"$regex":   regexPattern,
				"$options": "i", // 不区分大小写
			},
		}
	}

	// 不包含通配符，使用精确匹配
	return bson.M{
		"headWord": q,
	}
}
